/*!
* @file Coordinate.h
* @brief 三维坐标系
* @date 2024/9/12
*/
#pragma once

#include "Axis.h"

namespace data
{
class Rotation;

/*!
* @brief 三维坐标系
*/
class DATA_API Coordinate
{
public:
    using traits_type = std::numeric_limits<double>;

    Axis axis;
    Vector3d x;
    Vector3d y;

    /*!
    * @brief 坐标系构造
    */
    Coordinate() : axis(Vector3d(), Vector3d(0, 0, 1)), x(1, 0, 0), y(0, 1, 0) {}
    Coordinate(const Coordinate&) = default;
    Coordinate(Coordinate&&) = default;
    Coordinate(const Axis& a, const Vector3d& xd);
    ~Coordinate() = default;

    /*!
    * @brief 坐标系运算
    */
    Coordinate& operator=(const Coordinate&) = default;
    Coordinate& operator=(Coordinate&&) = default;

    void SetAxis(const Axis& axis);
    void SetAxes(const Axis& axis, const Vector3d& xd);
    void SetAxes(const Vector3d& n, const Vector3d& xd);

    const Vector3d& Position() const;
    void SetPosition(const Vector3d& pos);
    const Vector3d& X() const;
    void SetX(const Vector3d& dir);
    const Vector3d& Y() const;
    void SetY(const Vector3d& dir);
    const Vector3d& Z() const;
    void SetZ(const Vector3d& dir);

    void SetPlacement(const Placement& plm);
    void Transform(const Placement& plm);
    void Transform(const Rotation& rot);

    Vector3d ToLocalPoint(const Vector3d& pnt);
    Vector3d ToWorldPoint(const Vector3d& pnt);
};

/*!
* @brief 文本信息输出
*/
inline std::ostream& operator<< (std::ostream& stream, const Coordinate& c)
{
    return stream << "{ axis: " << c.axis << ", x: " << c.x << ", y: " << c.y << " }";
}
}  // namespace data
